package com.freemarker.db;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.freemarker.vo.ColumnEntity;
import com.freemarker.vo.DataTypeJavaField;
import com.freemarker.vo.DataTypeSources;
import com.freemarker.vo.HtmlEntity;
import com.freemarker.vo.TableEntity;

public class DataTypeConvertUtil {

	public static TableEntity toConvert(List<Map> queryColumnList, Map<String, String> queryTable) {

		TableEntity tableEntity = new TableEntity();
		String tableName = StringUtil.trim(queryTable.get("tableName"));
		String className = tableNameToClassName(tableName);

		tableEntity.setTableName(tableName);
		tableEntity.setClassName(className);
		tableEntity.setClassname(StringUtils.uncapitalize(className));
		tableEntity.setTableComment(queryTable.get("tableComment"));

		List<ColumnEntity> columnEntityList = new ArrayList<ColumnEntity>();

		for (int i = 0; i < queryColumnList.size(); i++) {
			Map queryMap = queryColumnList.get(i);
			ColumnEntity columnEntity = new ColumnEntity();

			String columnKey = StringUtil.trim(queryMap.get("columnKey"));

			String columnName = StringUtil.trim(queryMap.get("columnName"));
			columnEntity.setColumnName(columnName);

			if (Constants.isCamelCase) {
				String javaname = columnToJavaAttrName(columnName);
				columnEntity.setJavaname(javaname);
				columnEntity.setJavaName(javaAttrNameUpperCase(javaname));
			} else {
				columnEntity.setJavaname(columnName);
				columnEntity.setJavaName(javaAttrNameUpperCase(columnName));
			}

			columnEntity.setColumnComment(StringUtil.trim(queryMap.get("columnComment")));
			String columnDataType = StringUtil.trim(queryMap.get("dataType"));
			columnEntity.setColumnDataType(columnDataType);

			columnEntity.setJavaDataType(mySQLToJavaDataType(columnDataType, Constants.isWrapperDataType));
			columnEntity.setJavaDataTypeWrapper(mySQLToJavaDataType(columnDataType, true));

			columnEntity.setColumnExtra(StringUtil.trim(queryMap.get("columnExtra")));

			columnEntity.setDefaultValue(doInitFieldDefaultValue((String)queryMap.get("defaultValue"), columnDataType));

			String maxLengthStr = StringUtil.trim(queryMap.get("maxLength"));
			if (StringUtil.isNotEmpty(maxLengthStr)) {
				columnEntity.setColumnMaxLength(Long.parseLong(maxLengthStr));
			} else {
				columnEntity.setColumnMaxLength(0);
			}

			String nullable = StringUtil.trim(queryMap.get("nullable"));
			if ("NO".equals(nullable)) {
				columnEntity.setRequiredField(true);
			} else {
				columnEntity.setRequiredField(false);
			}

			if ("PRI".equalsIgnoreCase(columnKey)) {
				columnEntity.setPki(true);
				tableEntity.setPk(columnEntity);
			} else {
				columnEntity.setPki(false);
			}

			HtmlEntity htmlEntity = new HtmlEntity();
			htmlEntity.setJqueryValidateCss(getDataTypeJavaField(columnEntity.getColumnDataType()).getJqueryValidateCss());
			htmlEntity.setQueryClickEvent(getDataTypeJavaField(columnDataType).getQueryClickEvent());
			htmlEntity.setEditClickEvent(getDataTypeJavaField(columnDataType).getEditClickEvent());
			columnEntity.setHtmlEntity(htmlEntity);

			System.out.println(columnEntity.toString());
			columnEntityList.add(columnEntity);
		}

		tableEntity.setColumnList(columnEntityList);
		System.out.println(tableEntity.toString());
		return tableEntity;
	}

	/**
	 * mysql数据类型转换成java数据类型
	 * 
	 * @param columnDataType
	 * @return
	 */
	public static String mySQLToJavaDataType(String columnDataType, boolean isWrapperDataType) {
		String javaDateType = "";

		// 包装的数据类型
		if (isWrapperDataType) {
			javaDateType = getDataTypeJavaField(columnDataType).getJavaDataTypeWrapper();
		} else {
			javaDateType = getDataTypeJavaField(columnDataType).getJavaDataTypeBase();
		}

		return javaDateType;
	}

	/**
	 * <pre>
	 * jsp页面的值是否初始化，主要是对数字类型 
	 * 
	 * true：数据库字段的默认值优先，xml配置文件的默认值靠后
	 * </pre>
	 * @param dbFieldDefaultValue
	 * @param columnDataType
	 * @return
	 */
	public static String doInitFieldDefaultValue(String dbFieldDefaultValue, String columnDataType) {

		boolean isAutoInitFieldDefaultValue = Constants.isInitHtmlFieldDefaultValue;
		if (isAutoInitFieldDefaultValue) {
			if (StringUtil.isNotEmpty(dbFieldDefaultValue)) {
				return StringUtil.trim(dbFieldDefaultValue);
			}
			return getDataTypeJavaField(columnDataType).getDefaultValue();
		}
		return "";
	}
	

	/**
	 * 列名转换成java的属性名
	 * 
	 * <pre>
	 * 驼峰命名法
	 * </pre>
	 * 
	 * @param columnName
	 * @return
	 */
	public static String columnToJavaAttrName(String columnName) {
		String[] array = columnName.split("_");
		StringBuffer fileds = new StringBuffer();
		for (int i = 0; i < array.length; i++) {
			String ff = array[i];
			if (i == 0) {
				fileds.append(ff.toLowerCase());
			} else {
				if (ff == null || ff.length() == 0) {
					continue;
				} else if (ff.length() == 1) {
					fileds.append(ff);
				} else if (ff.length() > 1) {
					fileds.append(ff.substring(0, 1).toUpperCase()).append(ff.substring(1, ff.length()).toLowerCase());
				}
			}
		}
		return fileds.toString();
	}

	public static void main(String[] args) {
		String name = columnToJavaAttrName("user_uuid");
		System.out.println(name);
		System.out.println(javaAttrNameUpperCase(name));
	}

	/**
	 * 首字母大写
	 * 
	 * @param javaAttrName
	 * @return
	 */
	public static String javaAttrNameUpperCase(String javaAttrName) {
		StringBuffer fileds = new StringBuffer();
		if (javaAttrName.length() == 1) {
			fileds.append(javaAttrName.toUpperCase());
		} else if (javaAttrName.length() > 1) {
			fileds.append(javaAttrName.substring(0, 1).toUpperCase()).append(javaAttrName.substring(1, javaAttrName.length()));
		}
		return fileds.toString();
	}

	/**
	 * 表名转换成类名
	 * 
	 * @param tableName
	 * @return
	 */
	public static String tableNameToClassName(String tableName) {
		if (StringUtil.isEmpty(tableName)) {
			return "";
		}

		String[] array = tableName.split("_");
		StringBuffer sb = new StringBuffer("");
		for (int i = 0; i < array.length; i++) {
			String str = array[i];
			if (str.length() > 0) {
				if (str.length() == 1) {
					sb.append(str.toUpperCase());
				} else {
					String a = str.substring(0, 1);
					String b = str.substring(1);
					sb.append(a.toUpperCase()).append(b.toLowerCase());
				}
			}
		}
		return sb.toString();
	}

	public static DataTypeJavaField getDataTypeJavaField(String columnDataType) {
		DataTypeJavaField dataTypeJavaField = DataTypeSources.getDataTypeJavaField(columnDataType);
		if (dataTypeJavaField == null) {
			throw new NullPointerException("columnDataType [" + columnDataType + "] not find javaDataType in " + DataTypeSources.xmlName);
		}
		return dataTypeJavaField;
	}

}
